/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package mapmakerapp;

import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.*;
/**
 *
 * @author Administrator
 */
public class ImageTools {
    public static final int FLIP_NONE = 0;
    public static final int FLIP_HORIZONTAL = 1;
    public static final int FLIP_VERICAL = 2;
    
    public static BufferedImage imageFlip(BufferedImage originImg, int typeFlip)
    {
        BufferedImage imgFliped = null;
        
        switch(typeFlip)
        {
            case FLIP_NONE:
                return originImg;

            case FLIP_HORIZONTAL:
                AffineTransform tx = AffineTransform.getScaleInstance(-1, 1);
                tx.translate(-originImg.getWidth(null), 0);
                AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
                imgFliped = op.filter(originImg, null);

                break;

            case FLIP_VERICAL:
                tx = AffineTransform.getScaleInstance(1, -1);
                tx.translate(0, -originImg.getHeight(null));
                op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
                imgFliped = op.filter(originImg, null);
                
                break;

            default:
                break;
        }

        return imgFliped;
    }

    public static BufferedImage imageRotate(BufferedImage originImg, int degree)
    {       
        double radians = (Math.PI / 180) * degree;

        AffineTransform tx = new AffineTransform();
        //tx.scale(scalex, scaley);
        //tx.rotate(radians, originImg.getWidth(null)/2, originImg.getHeight(null)/2);

         /*
         * translate to make sure the rotation doesn't cut off any image data
         */
        //AffineTransform translationTransform;
        //translationTransform = findTranslation(tx, originImg);
        //tx.preConcatenate(translationTransform);

        double sin = Math.abs(Math.sin(radians)), cos = Math.abs(Math.cos(radians));
        int w = originImg.getWidth(), h = originImg.getHeight();
        int neww = (int)Math.floor(w*cos+h*sin), newh = (int)Math.floor(h*cos+w*sin);

        tx.translate((neww-w)/2, (newh-h)/2);
        tx.rotate(radians, originImg.getWidth(null)/2, originImg.getHeight(null)/2);
        
        AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);        
        BufferedImage img = op.filter(originImg, null);
        
        return img;
    }

    public static void drawRect(int x, int y, int width, int height, Graphics2D g2, int degree)
    {
        double radians = (Math.PI / 180) * degree;
        AffineTransform aT = g2.getTransform();

        // create point
        /*AffineTransform transformer = AffineTransform.getRotateInstance(radians,0,0);
        Point2D before = new Point2D.Double( x , y );
        // create point to hold result
        Point2D after = new Point2D.Double();
        // transform the point
        after = transformer.transform ( before, after );

        double newX = after.getX();
        double newY = after.getY();*/
        
        Rectangle2D rect = new Rectangle2D.Double(x, y, width, height);
	AffineTransform tx = new AffineTransform();

        double sin = Math.abs(Math.sin(radians)), cos = Math.abs(Math.cos(radians));
        int w = width, h = height;
        int neww = (int)Math.floor(w*cos+h*sin), newh = (int)Math.floor(h*cos+w*sin);
        
        tx.translate((neww-w)/2, (newh-h)/2);
        tx.rotate(radians, x + width/2, y + height/2);
        
        g2.transform(tx);
	g2.draw(rect);
	g2.setTransform(aT);
    }

    public static BufferedImage imageScale(BufferedImage originImg, float scale)
    {
        AffineTransform tx = new AffineTransform();
        tx.scale(scale, scale);             

        AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
        return op.filter(originImg, null);

    }
    /*
   * find proper translations to keep rotated image correctly displayed
   */
  private static AffineTransform findTranslation(AffineTransform at, BufferedImage bi) {
        Point2D p2din, p2dout;

        p2din = new Point2D.Double(0.0, 0.0);
        p2dout = at.transform(p2din, null);
        double ytrans = p2dout.getY();

        p2din = new Point2D.Double(0, bi.getHeight());
        p2dout = at.transform(p2din, null);
        double xtrans = p2dout.getX();

        AffineTransform tat = new AffineTransform();
        tat.translate(-xtrans, -ytrans);
        return tat;
  }
}
